﻿using IOP.SgrA;
using IOP.SgrA.SilkNet.Vulkan;
using Microsoft.Extensions.Logging;
using Silk.NET.Vulkan;
using System;

namespace VkSample112;

public class MainMiddleware : IProductionLineMiddleware<PrimaryVulkanRenderGroup>
{
    public void Invoke(PrimaryVulkanRenderGroup group, RenderingProductionLineDelegate<PrimaryVulkanRenderGroup> next)
    {
        try
        {
            var queue = group.WorkQueues[0].Queue;
            var cmdBuffer = group.PrimaryCommandBuffer;
            var semaphores = group.Semaphores;
            var pass = group.RenderPass;
            var face = group.Fences;
            var lDevice = group.LogicDevice;

            VulkanFrameBuffer framebuffer = group.RenderPass.GetFramebuffer(group.CurrentFrame);
            cmdBuffer.Reset();
            cmdBuffer.Begin();
            cmdBuffer.BeginRenderPass(pass, framebuffer, pass.BeginOption, SubpassContents.SecondaryCommandBuffers);
            group.SecondaryGroupRendering(pass, framebuffer);
            cmdBuffer.ExecuteCommands(group.GetUpdateSecondaryBuffers());
            cmdBuffer.EndRenderPass();
            cmdBuffer.End();

            var submitInfo = new SubmitOption
            {
                WaitDstStageMask = new PipelineStageFlags[] { PipelineStageFlags.ColorAttachmentOutputBit },
                WaitSemaphores = new Silk.NET.Vulkan.Semaphore[] { semaphores[0] },
                Buffers = new CommandBuffer[] { cmdBuffer.RawHandle },
                SignalSemaphores = new Silk.NET.Vulkan.Semaphore[] { semaphores[1] }
            };
            lDevice.Submit(queue, face[0], submitInfo);
            Result r = Result.Timeout;
            do
            {
                r = group.LogicDevice.WaitForFences(face, true, 100000000);
            } while (r == Result.Timeout);
            group.LogicDevice.ResetFences(face);
        }
        catch (Exception e)
        {
            group.Logger.LogError(e.Message + "\r\n" + e.StackTrace);
            group.Disable();
        }
    }
}
